Sentinel基本使用

您所在的位置:网站首页 qps qpm Sentinel基本使用

Sentinel基本使用

2024-07-07 20:42| 来源: 网络整理| 查看: 265

随着微服务的流行,服务和服务之间的稳定性变得越来越重要。Sentinel 是面向分布式服务架构的轻量级流量控制框架,主要以流量为切入点,从流量控制、熔断降级、系统负载保护等多个维度来帮助您保护服务的稳定性。

流量控制有以下几个角度:

资源的调用关系,例如资源的调用链路,资源和资源之间的关系;运行指标,例如 QPS、线程池、系统负载等;控制的效果,例如直接限流、冷启动、排队等。

Sentinel 的设计理念是让用户可以自由选择控制的角度,并进行灵活组合,从而达到想要的效果。

一, Sentinel 的使用可以分为两个部分:

核心库(Java 客户端):不依赖任何框架/库,能够运行于 Java 7 及以上的版本的运行时环境,同时对 Dubbo / Spring Cloud 等框架也有较好的支持。控制台(Dashboard):Dashboard主要负责管理推送规则;监控;管理机器信息等。基于 Spring Boot 开发,打包后可以直接运行,不需要额外的 Tomcat 等应用容器。

二, 引入核心库和客户端与dashboard控制台通信的依赖

com.alibaba.csp sentinel-core 1.4.0     com.alibaba.csp     sentinel-transport-simple-http 1.4.0

三, 定义资源

资源 是 Sentinel 中的核心概念之一。最常用的资源是我们代码中的 Java 方法, 它可以是 Java 应用程序中的任何内容, 或是应用程序提供某一项服务的业务代码, 或是应用程序调用其他应用提供的服务接口, 或者直接就是一段代码, 由此可知sentinel中的资源可以是应用程序中具体的某一行代码, 流控的粒度非常细.

只要通过 Sentinel API 定义的代码,就是资源,能够被 Sentinel 保护起来。大部分情况下,可以使用方法签名,URL,甚至服务名称作为资源名来标示资源。

例如: 使用Sentinel Api将被访问的资源包围起来.

Entry entry = null; // 务必保证finally会被执行 try { // 资源名可使用任意有业务语义的字符串 entry = SphU.entry("自定义资源名"); // 被保护的业务逻辑, 即被保护的资源 // do something... } catch (BlockException e1) { // 资源访问阻止,被限流或被降级 // 进行相应的处理操作 } finally { if (entry != null) { entry.exit(); } }

四, 定义访问该资源的规则

资源定义完成后, 就需要对该资源定义一些访问规则, 如针对上面的资源, 基于QPS的流行控制形式, 采用默认的RuleConstant.CONTROL_BEHAVIOR_DEFAULT;配置每秒最多允许通过20次请求.

private static void initFlowRules(){ List rules = new ArrayList(); FlowRule rule = new FlowRule(); rule.setResource("HelloWorld"); rule.setGrade(RuleConstant.FLOW_GRADE_QPS); // Set limit QPS to 20. rule.setCount(20); rules.add(rule); FlowRuleManager.loadRules(rules); }

五, 启动sentinel dashboard控制台

下载sentinel-dashboard.jar

使用下面命令启动dashboard:

java -Dserver.port=8080 -jar sentinel-dashboard.jar

-Dserver.port=8080为sentinel控制台的启动端口, 如下就代表着启动成功.

访问控制台: 由于现在还没有任何客户端接入控制台, 所以看不到应用.

六, 客户端接入dashboard控制台

这里以sentinel自带的sentinel-demo-basic自带的demo为例, 运行FlowQpsDemo类, 并配置上控制台地址.

-Dcsp.sentinel.dashboard.server=127.0.0.1:8080 -- sentinel 控制台ip:port -Dcsp.sentinel.api.port=8719 -- 客户端用于接收控制台流控规则端口号 -Dproject.name=FlowQpsDemo -- 名称

FlowQpsDemo类,

1 首先定义资源, 成功访问资源时pass+1, 阻止访问资源时会抛出BlockException则block+1.

2 接着定义访问资源的规则:

rule1.setResource(KEY);资源名,即限流规则的作用对象

rule1.setCount(20);设置允许通过的最大请求数20; 限流阈值

rule1.setGrade(RuleConstant.FLOW_GRADE_QPS);设置限流阈值类型, QPS 或线程数模式, 默认是QPS. 

rule1.setLimitApp("default");流控针对的调用来源,若为 default 则不区分调用来源

这里没有在代码显示的配置流控效果, 而当流量超过阈值时, 默认采用的流控效果就是直接拒绝即快速失败, 或者我们也可以直接配置上:

rule1.setControlBehavior(RuleConstant.CONTROL_BEHAVIOR_DEFAULT); 

下面配上流控规则定义的一些重要属性:

Field说明默认值resource资源名,资源名是限流规则的作用对象 count限流阈值 grade限流阈值类型,QPS 或线程数模式QPS 模式limitApp流控针对的调用来源default,代表不区分调用来源strategy判断的根据是资源自身,还是根据其它关联资源 (refResource),还是根据链路入口根据资源本身controlBehavior流控效果(直接拒绝 / 排队等待 / 慢启动模式)直接拒绝

同一个资源可以同时有多个限流规则。

public class FlowQpsDemo { private static final String KEY = "abc"; // 统计通过数 private static AtomicInteger pass = new AtomicInteger(); // 统计阻止数 private static AtomicInteger block = new AtomicInteger(); // 统计总数 private static AtomicInteger total = new AtomicInteger(); private static volatile boolean stop = false; private static final int threadCount = 32; // 运行100s private static int seconds = 60 + 40; public static void main(String[] args) throws Exception { // 初始化流控规则 initFlowQpsRule(); // 1s计时统计, pass, block, total tick(); // 模拟开启32个线程并发访问资源 simulateTraffic(); System.out.println("===== begin to do flow control"); System.out.println("only 20 requests per second can pass"); } private static void initFlowQpsRule() { List rules = new ArrayList(); FlowRule rule1 = new FlowRule(); rule1.setResource(KEY); // set limit qps to 20 rule1.setCount(20); rule1.setGrade(RuleConstant.FLOW_GRADE_QPS); rule1.setLimitApp("default"); rules.add(rule1); FlowRuleManager.loadRules(rules); } private static void simulateTraffic() { for (int i = 0; i < threadCount; i++) { Thread t = new Thread(new RunTask()); t.setName("simulate-traffic-Task"); t.start(); } } static class RunTask implements Runnable { @Override public void run() { while (!stop) { Entry entry = null; try { entry = SphU.entry(KEY); // token acquired, means pass pass.addAndGet(1); } catch (BlockException e1) { block.incrementAndGet(); } catch (Exception e2) { // biz exception } finally { total.incrementAndGet(); if (entry != null) { entry.exit(); } } Random random2 = new Random(); try { TimeUnit.MILLISECONDS.sleep(random2.nextInt(50)); } catch (InterruptedException e) { // ignore } } } } private static void tick() { Thread timer = new Thread(new TimerTask()); timer.setName("sentinel-timer-task"); timer.start(); } static class TimerTask implements Runnable { @Override public void run() { long start = System.currentTimeMillis(); System.out.println("begin to statistic!!!"); long oldTotal = 0; long oldPass = 0; long oldBlock = 0; while (!stop) { try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { } long globalTotal = total.get(); long oneSecondTotal = globalTotal - oldTotal; oldTotal = globalTotal; long globalPass = pass.get(); long oneSecondPass = globalPass - oldPass; oldPass = globalPass; long globalBlock = block.get(); long oneSecondBlock = globalBlock - oldBlock; oldBlock = globalBlock; System.out.println(seconds + " send qps is: " + oneSecondTotal); System.out.println(TimeUtil.currentTimeMillis() + ", total:" + oneSecondTotal + ", pass:" + oneSecondPass + ", block:" + oneSecondBlock); if (seconds--


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3